<template>
    <ul class="c-tree">
        <c-treenode v-for="(child, idx) in treeData" :key="child.id"
                    :node="child" :set="set"
                    :last="idx === treeData.length - 1"
        ></c-treenode>
    </ul>
</template>

<script>

    import Tools from '../../tools/tools';
    import defaultSet from './setting';
    import Utils from './utils';

    export default {
        name: "CTree",
        props: {
            // 树数据
            data: {type: Array, default() { return [];}},
            // 所有配置
            setting: {type: Object, default() { return {};}}
        },
        data() {
            return {
                set: Tools.extend({}, defaultSet, this.setting || {}),
                treeData: [], // 树形结构数据
                flatData: [], // 扁平结构数据
            };
        },
        computed: {
            // 所有树节点对象
            nodesObj() {
                const tmp = {};
                this.flatData.forEach(v => tmp[v.id] = v);
                return tmp;
            }
        },
        mounted() {
            this.build();
            this.$on('on-select', this.handleSelectNode);
            this.$on('on-check', this.handleCheckNode);
        },
        beforeDestroy() {
            this.$off('on-select', this.handleSelectNode);
            this.$off('on-check', this.handleCheckNode);
        },
        methods: {
            // 重构树
            build() {
                const arr = [];
                this.treeData = Utils.creatTree(this.data, this.set, arr);
                this.flatData = arr;
            },
            // 单选
            handleSelectNode(id) {
                this.flatData.forEach(v => v.selected = false);
                let node = this.nodesObj[id];
                if (node) {
                    node.selected = true;
                }
            },
            // 复选树节点
            handleCheckNode({checked, id}) {
                let node = this.nodesObj[id];
                if (node) {
                    node.checked = checked;
                    this.setRawVal(node, 'checked', checked);

                    // 向下关联
                    if ((checked && this.set.check.checkedDown) || (!checked && this.set.check.checkCancelDown)) {
                        let nodes = node.children.slice(0);
                        while (nodes.length) {
                            const v = nodes.shift();
                            v.checked = checked;
                            this.setRawVal(v, 'checked', checked);
                            nodes = nodes.concat(v.children || []);
                        }
                    }

                }
            },
            // 设置原有属性，如果原数据有属性，则设置
            setRawVal(node, key, val) {
                const k = this.set.key[key];
                if (node.raw.hasOwnProperty(k)) {
                    node.raw[k] = val;
                }
            },

            // api 根据id获取树节点
            getNodeById(id) {
                return this.nodesObj[id] || null;
            },
        }
    };
</script>
